# -*- coding: utf-8 -*-
import cv2
import numpy as np
import logging


def load_image_by_bytes(image_bytes):
    """
    通过字节加载图片
    :param image_bytes: 图像的字节
    :return: 灰度后的图片
    """
    return cv2.imdecode(np.asarray(bytearray(image_bytes), dtype=np.uint8), cv2.IMREAD_GRAYSCALE)


def load_image_by_filename(filename):
    """
    通过文件名加载图片
    :param filename: 图片名称
    :return: 灰度后的图片
    """
    return cv2.imread(filename, cv2.IMREAD_GRAYSCALE)


def default_cut_hack_func(char_image, w, char_image_width):
    return [char_image]


def cut_image(image_narray, ignore_func, char_image_width, char_image_height, hack_func=default_cut_hack_func):
    """
    切割图片
    :param image_narray: 要切割的图片
    :param ignore_func: 忽略矩阵的函数
    :param char_image_width: 单个字符宽度
    :param char_image_height: 单个字符高度
    :param hack_func hack func
    :return: 返回单个字符图片列表
    """
    _, contours, hierarchy = cv2.findContours(image_narray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    rects = []
    for i in range(0, len(hierarchy[0])):
        if hierarchy[0][i][3] == 0:
            rects.append(cv2.boundingRect(contours[i]))
    rects = sorted(rects, key=lambda rect: rect[0], reverse=False)
    images = []
    for i, rect in enumerate(rects):
        x, y, w, h = rect
        if not ignore_func(x, y, w, h):
            char_image = image_narray[y:y + h, x:x + w]
            char_images = hack_func(char_image, w, char_image_width)
            for j in range(len(char_images)):
                images.append(
                    image_padding(char_images[j], char_image_width, char_image_height))
    return images


def image_padding(image, char_image_width, char_image_height, fill_value=255):
    """
    将传入的图像填充到指定大小
    :param image:
    :param char_image_width: 宽度
    :param char_image_height: 高度
    :param fill_value: 填充值，默认255
    :return: 填充后的图像
    """
    logger = logging.getLogger()
    w, h = char_image_width, char_image_height
    if image.shape[0] > w or image.shape[1] > h:
        # cv2.imshow('err_image', image)
        # cv2.waitKey()
        # cv2.destroyAllWindows()
        logger.fatal(
            'max w is %d, h is %d.' % (image.shape[0], image.shape[1]))
        exit(1)
    if w - image.shape[0] > 0:
        row_padding = np.zeros((w - image.shape[0], image.shape[1]), dtype=np.uint8) + fill_value
        image = np.row_stack((image, row_padding))

    if h - image.shape[1] > 0:
        column_padding = np.zeros((image.shape[0], h - image.shape[1]), dtype=np.uint8) + fill_value
        image = np.column_stack((image, column_padding))
    return image
